﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Management.Instrumentation;
using System.Management;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Collections;
using System.Timers;

namespace  cpu_workload
{
    public class cpu
    {
        int a, b;

       public int getCPUfrequency()       // Function for get the CPU frequency, which will be used for computing loop times.
        {
            ManagementClass m = new ManagementClass("Win32_Processor");
            ManagementObjectCollection mn = m.GetInstances();
            ManagementObjectSearcher MySearcher = new ManagementObjectSearcher("SELECT * FROM Win32_Processor");
            foreach (ManagementObject MyObject in MySearcher.Get())
            {
                a = Convert.ToInt32(MyObject.Properties["CurrentClockSpeed"].Value);
               // System.Console.WriteLine(MyObject["Name"].ToString());
                //System.Console.WriteLine("CPU frequency：" + MyObject.Properties["CurrentClockSpeed"].Value.ToString());
            }
            return a;
        }
        public int getCPUcore()                                //Function for measuring core numbers in CPU .
        {
            ManagementClass m = new ManagementClass("Win32_Processor");
            ManagementObjectCollection mn = m.GetInstances();
            ManagementObjectSearcher MySearcher = new ManagementObjectSearcher("SELECT * FROM Win32_Processor");
            foreach (ManagementObject MyObject in MySearcher.Get())
            {
                PropertyDataCollection properties = MyObject.Properties;
                //System.Console.WriteLine("Number Of Cores:" + properties["NumberOfCores"].Value + "\r");
                b = Convert.ToInt32(properties["NumberOfCores"].Value);
                //System.Console.WriteLine("Number Of Cores:" + b + "\r");
            }
            return b;
        }
        public void ThreadForCpuView()   // Function to monitor CPU usage.
        {
            float f = 0;
            PerformanceCounter[] counters = new PerformanceCounter[System.Environment.ProcessorCount];
            for (int i = 0; i < counters.Length; i++)
            {
                counters[i] = new PerformanceCounter("Processor", "% Processor Time", i.ToString());
            }

            while (true)
            {
                for (int i = 0; i < counters.Length; i++)
                {
                    f = counters[i].NextValue() + f;
                    //Console.WriteLine("CPU-{0}: {1:f}%", i, f);
                }
               
         //       Console.WriteLine("CPU:" + f);
           //     Console.WriteLine();
                System.Threading.Thread.Sleep(1000);
                f = 0;
            }
        }
        public class CPUcontrol                   // Function to control CPU in a stable condition.
        {
            int q, b, d;
           
            public void running( )  // floating around 50%
            {
               // System.Console.WriteLine(b);
                System.Diagnostics.PerformanceCounter p = new System.Diagnostics.PerformanceCounter("Processor", "% Processor Time", "_Total");
                if (p == null)
                {
                    return;
                }
                while (true)
                {
                   if (p.NextValue() > 50)
                       System.Threading.Thread.Sleep(5);
                }
             
            }
            public void running2()   // floating around 100%
            {
                
                    while(true)
                    {

                    }
            }
        }
   
        public class Programcpu
        {
            [DllImport("kernel32.dll")]
            static extern uint GetTickCount();

            //SetThreadAffinityMask Set thThread on the core you want dwThreadAffinityMask
            [DllImport("kernel32.dll")]
            static extern UIntPtr SetThreadAffinityMask(IntPtr hThread,
                                UIntPtr dwThreadAffinityMask);

            //get the  handler
            [DllImport("kernel32.dll")]
            static extern IntPtr GetCurrentThread();

            [DllImport("user32.dll", EntryPoint = "ShowWindow", SetLastError = true)]
            static extern bool ShowWindow(IntPtr hWnd, uint nCmdShow);
            [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
            public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
     
            public static void Main(string[] args)
            {

                   Console.Title = "CPU grnerator"; //Title for console
                   IntPtr a = FindWindow("ConsoleWindowClass", "CPU grnerator");
                   if (a != IntPtr.Zero)
                       ShowWindow(a, 0); //hide the console
                
                int  b = 0, k = 0 ;
                cpu x = new cpu();
                CPUcontrol CpuControl = new CPUcontrol();
                
                
                b = x.getCPUcore();
                Thread[] threads = new Thread[8];
               
                /*Console.Write("Enter condition number(1-3):");
                string Condition = Console.ReadLine();
                o = Convert.ToInt32(Condition);

                if (o < 4 && o > 0)
                    Console.WriteLine(" Condition " + Condition);
                else
                    Console.WriteLine(" Enry error");

                o = Convert.ToInt32(Condition);
                //Console.WriteLine(o);
                DateTime d1 = DateTime.Now;
                Console.WriteLine(d1);*/

                if (b == 4)                      // for quad-core CPU
                {
                    
                    SetThreadAffinityMask(GetCurrentThread(), new UIntPtr(0x0001));
                    Thread t0 = new Thread(new ThreadStart(CpuControl.running));

                    threads[0] = t0;

                    SetThreadAffinityMask(GetCurrentThread(), new UIntPtr(0x0002));
                    Thread t1 = new Thread(new ThreadStart(CpuControl.running));

                    threads[1] = t1;

                    SetThreadAffinityMask(GetCurrentThread(), new UIntPtr(0x0003));
                    Thread t2 = new Thread(new ThreadStart(CpuControl.running));

                    threads[2] = t2;

                    SetThreadAffinityMask(GetCurrentThread(), new UIntPtr(0x0004));
                    Thread t3 = new Thread(new ThreadStart(CpuControl.running));
                   //  Thread t4 = new Thread(new ThreadStart( x.ThreadForCpuView));
                    threads[3] = t3;
                    
                            for (int i = 0; i < 4; i++)
                            {
                                threads[i].Start();
                            }
                           
                           
                          
                 }
                else if (b == 2)               // for dual-core CPU
                {
                    
                    SetThreadAffinityMask(GetCurrentThread(), new UIntPtr(0x0001));
                    Thread t0 = new Thread(new ThreadStart(CpuControl.running));
                    threads[0] = t0;
                    SetThreadAffinityMask(GetCurrentThread(), new UIntPtr(0x0002));
                    Thread t1 = new Thread(new ThreadStart(CpuControl.running));
                   //  Thread t2 = new Thread(new ThreadStart(x.ThreadForCpuView));
                    threads[1] = t1;
                    //  threads[2] = t2;
                    for (int i = 0; i < 3; i++)
                    {
                        threads[i].Start();
                    }
                }
                else if (b == 1)           // for singal core
                {
                    while (true)
                    {
                  
                    //SetThreadAffinityMask(GetCurrentThread(), new UIntPtr(0x0001));
                    Thread t0 = new Thread(new ThreadStart(CpuControl.running));
                    threads[0] = t0;
                 
                    Thread t1 = new Thread(new ThreadStart(x.ThreadForCpuView));
                    threads[1] = t1;
                    Thread t2 = new Thread(new ThreadStart(CpuControl.running2));
                    threads[2] = t2;
                            threads[1].Start();      //start monitior CPU usage
                          //  Console.WriteLine("*************idle**************");
                           Thread.Sleep(40000);    //  idle condition
                            threads[0].Start();    //  start  50% condition
                          //  Console.WriteLine("************50% condition**********");
                            Thread.Sleep(40000);
                           
                           threads[0].Abort();   // shut thread0 down 
                            threads[2].Start();  //  start  100% condition
                          // Console.WriteLine("**********100% condition***********");
                            Thread.Sleep(40000);
                           threads[2].Abort();  // shut thread2 down 
                            threads[1].Abort(); // shut thread1 down 
                            k++;
                            if (k == 1) break;  // end
                    }
                }
            }
        }
    }
}
